class Solution {
    public int coinChange(int[] coins, int amount) {
        return package01(coins, amount);
    }
    private int regularDP(int[] coins, int amount) {
        int[] opt = new int[amount + 1];
        // 设一个合适的值即可，不要设得太大，下边有+1操作，直接用Integer.MAX_VALUE会溢出
        int maxValue = amount + 1;
        Arrays.fill(opt, maxValue);
        opt[0] = 0;
        for (int i = 1; i <= amount; i++) {
            for (int j = 0; j < coins.length; j++) {
                if (i - coins[j] >= 0) {
                    opt[i] = Math.min(opt[i], opt[i - coins[j]] + 1);
                }
            }
        }
        if (opt[amount] >= maxValue) {
            opt[amount] = -1;
        }
        return opt[amount];
    }
    private int package01(int[] coins, int amount) {
        int maxValue = amount+1;
        int[] f = new int[maxValue];
        Arrays.fill(f, maxValue);
        f[0] = 0;
        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                f[j] = Math.min(f[j], f[j-coins[i]]+1);
            }
        }
        if (f[amount] == maxValue) {
            f[amount] = -1;
        }
        return f[amount];
    }
}
